//	--------------------------------------------------------------------
//	Copyright(C) 2006,2007 Zhao Yukun. All rights reserved.
//	This file is a part of the Xeres system.
//	Xeres 2007
//	Contact : xeres.engine@gmail.com
//	$(reservedInfo)
//	$(reservedDeclaration)
//	--------------------------------------------------------------------
///	@file	<database.h>
///	@path	~/src/database/
///	@date	2007/06/15
///	@desc	Database global declarations.

#pragma once

#include "xeres.h"

#include <vector>

#include "lib/utilities/time.h"

namespace xeres {

	/*!
		\enum		DataType
		\brief		Data types in data manager.

		\sa IData
	*/
	enum DataType
	{
		/// \brief Empty entry data.
		DATA_NULL = 0 ,	
		/// \brief Data is a binary block
		/// \sa CBinaryEntry
		DATA_BIN ,
		/// \brief Data is a value.
		/// \sa CValueEntry, CVarProxyEntry
		DATA_VAR ,
		/// \brief Data is a node.
		/// \sa CXmlNodeEntry, CNodeProxyEntry
		DATA_NODE ,
		/// \brief Data is a file.
		/// \sa CDataFileEntry
		DATA_FILE ,
		/// \brief Data is a directory.
		/// \sa CDirectoryEntry
		DATA_DIR ,		
		DATA_last
	};

	/*!
		\struct		DataInfo
		\brief		Presents data informations.
	*/
	struct DataInfo
	{
		/// \brief Data type.
		DataType	m_type;
		/// \brief Data size in byte. Some special data will be zero.
		uint64		m_size;

		/// \brief Last modified time. Only available for file.
		DateTime	m_modified;
		/// \brief Created time. Only available for file.
		DateTime	m_created;
		/// \brief Last accessed time. Only available for file.
		DateTime	m_accessed;
	};

	// Key identifier.
	typedef const wchar_t *		Identifier;

	/*!
		\class		Key
		\brief		Key to access data system.
	*/
	class Key
	{
	public:

		// pass a key by return value
		class KeyPass
		{
		public:
			/// \ctor
			KeyPass( Identifier id );

			/// \ctor_copy
			KeyPass( const KeyPass& pass );

			/// \dtor
			~KeyPass( void );

			/*!
				\brief		Determine if key is valid.
			*/
			bool IsValid( void ) const { return m_id != NULL; }

		private:

			friend class Key;

		//@ data
			mutable Identifier	m_id;
		};

		/// \name Constructor & Destructor
		//@{

		/// \ctor
		Key( void );

		/// \ctor_set
		Key( const wchar_t * str );

		/// \ctor_set
		Key( const WString& str );

		/// \ctor_set
		Key( const KeyPass& pass );

		/// \ctor_copy
		Key( const Key& rhs );

		/// \dtor
		~Key( void );

		//@}

	//@ local

		/*!
			\brief		Determine if key is valid.
		*/
		bool IsValid( void ) const { return m_key != NULL; }

		/*!
			\brief		Get string of key.
		*/
		WString GetString( void ) const { return WString( m_key ); }

		/*!
			\brief		Get c-type string.
		*/
		const wchar_t * GetCStr( void ) const { assert(m_key); return static_cast<const wchar_t*>( m_key ); }

		/*!
			\brief		Assignment, notice only INVALID key can assign new value.
		*/
		Key& operator = ( const Key& value );

		/*!
			\brief		Comparison.
		*/
		bool operator == ( const Key& value ) const { return m_key == value.m_key; }

		/*!
			\brief		Comparison.
		*/
		bool operator != ( const Key& value ) const { return m_key != value.m_key; }

		/*!
			\brief		Comparison, for STL container.
		*/
		friend bool operator < ( const Key& left , const Key& right ) { return left.m_key < right.m_key; }

		/*!
			\brief		Comparison, for STL container.
		*/
		friend bool operator > ( const Key& left , const Key& right ) { return left.m_key > right.m_key; }

		/*! 
			\brief		Conversion.
		*/
		operator WString ( void ) { return GetString(); }

		/*!
			\brief		Query if a key exists.
		*/
		static KeyPass QueryKey( const WString& name );

		/*!
			\brief		Query a serial of key.
		*/
		static bool QueryKeys( const StringSeq& names , std::vector<Key>& keys );

		/*!
			\brief		Make a key.
		*/
		static KeyPass MakeKey( const WString& name );

	private:

	//@ data
		Identifier		m_key;
	};

} // namespace xeres

#include "database/database.inl"
